<?php

namespace App\Services;

use App\Models\Province;
use GuzzleHttp\Exception\GuzzleException;
use Psr\Log\LoggerInterface;
use Illuminate\Support\Facades\DB;

class ProvinceProBatchLineSpiderService extends ProvinceBatchLineSpiderService
{
    /**
     * 采集省份专业批次线数据
     *
     * @param int|null $limit 限制采集的省份数量
     * @return array 采集统计信息
     * @throws GuzzleException
     */
    public function fetchProvinceProBatchLines(?int $limit = null): array
    {
        $this->initProxyPool();
        $provinceIds = $this->getProvinceIds($limit);
        $stats = ['total' => 0, 'success' => 0, 'failed' => 0];

        foreach ($provinceIds as $provinceId) {
            $stats['total']++;
            try {
                $data = $this->fetchProvinceData($provinceId);
                $this->saveProBatchLines($provinceId, $data);
                $stats['success']++;
            } catch (\Exception $e) {
                $this->logError($provinceId, $e);
                $stats['failed']++;
            }
        }

        return $stats;
    }

    /**
     * 获取省份数据
     *
     * @param int $provinceId
     * @return array
     * @throws GuzzleException
     */
    protected function fetchProvinceData(int $provinceId): array
    {
        $url = "https://static-data.gaokao.cn/www/2.0/proprovince/{$provinceId}/pro.json?a=www.gaokao.cn";
        $response = $this->withRetry(function () use ($url) {
            return $this->httpClient->get($url, [
                'proxy' => $this->getNextProxy(),
                'timeout' => config('spider.default.timeout'),
            ]);
        });

        $data = json_decode($response->getBody(), true);
        if (json_last_error() !== JSON_ERROR_NONE || $data['code'] !== '0000') {
            throw new \RuntimeException('Invalid API response: ' . json_last_error_msg());
        }

        return $data['data'] ?? [];
    }

    /**
     * 保存专业批次线数据
     *
     * @param int $provinceId
     * @param array $data
     */
    protected function saveProBatchLines(int $provinceId, array $data): void
    {
        $province = Province::find($provinceId);
        if (!$province) {
            throw new \RuntimeException("Province not found: {$provinceId}");
        }

        $batchLines = [];
        foreach ($data as $year => $yearData) {
            foreach ($yearData as $tType => $items) {
                foreach ($items as $item) {
                    $batchLines[] = [
                        'batch' => $item['batch'] ?? null,
                        'batch_name' => $item['batch_name'] ?? null,
                        'convention_batch' => $item['convention_batch'] ?? false,
                        'diff' => $item['diff'] ?? null,
                        'major_score' => $item['major_score'] ?? null,
                        'name' => $item['name'] ?? null,
                        'province' => $item['province'] ?? $province->name,
                        'rank' => $item['rank'] ?? null,
                        'score' => $item['score'] ?? null,
                        'score_section' => $item['score_section'] ?? null,
                        'type' => $item['type'] ?? null,
                        'type_name' => $item['type_name'] ?? null,
                        'year' => $item['year'] ?? $year,
                        't_type' => $tType,
                    ];
                }
            }
        }

        DB::table('province_batch_line')->upsert(
            $batchLines,
            ['province', 'year', 'batch', 'type', 't_type'],
            ['batch_name', 'convention_batch', 'diff', 'major_score', 'name', 'rank', 'score', 'score_section', 'type_name']
        );
    }
}
